package com.face.util;

import com.face.common.UserInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.List;

public class JwtUtil {
    private static final String APP_ID = "APP_ID";
    private static final String APP_SECRET = "APP_SECRET";
    //Sample method to construct a JWT
    public static String createJWT(UserInfo userInfo, String issuer, long ttlMillis) {

        //The JWT signature algorithm we will be using to sign the token
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //We will sign our JWT with our ApiKey secret
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary( APP_ID + APP_SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().claim(JwtConstans.JWT_KEY_USER_NAME,userInfo.getUsername())
                .claim(JwtConstans.JWT_KEY_SHOPID,userInfo.getShopId())
                .claim(JwtConstans.JWT_KEY_STATUS, userInfo.getStatus())
                .claim(JwtConstans.JWT_KEY_PERMS, userInfo.getPerms())
                .setIssuedAt(now)
                .setIssuer(issuer)
                .signWith(signatureAlgorithm, signingKey);

        //if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        //Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();

    }

    public static UserInfo parseJWT(String jwt) {

        //This line will throw an exception if it is not a signed JWS (as expected)
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(APP_ID + APP_SECRET))
                .parseClaimsJws(jwt).getBody();

        return new UserInfo(ObjectUtils.toString(claims.get(JwtConstans.JWT_KEY_USER_NAME)), ObjectUtils.toString(claims.get(JwtConstans.JWT_KEY_SHOPID)),
                ObjectUtils.toInt(claims.get(JwtConstans.JWT_KEY_STATUS)), (List<String>) claims.get(JwtConstans.JWT_KEY_PERMS));
    }
}
